package com.ehome.poct.terminal.service;

import cn.hutool.core.util.StrUtil;
import com.ehome.context.thread.UserThreadLocal;
import com.ehome.core.page.Page;
import com.ehome.core.page.PageInfo;
import com.ehome.exception.BizException;
import com.ehome.poct.base.api.dto.doctor.TermClinicDTO;
import com.ehome.poct.base.api.feign.ClinicClient;
import com.ehome.poct.core.api.dto.DelReportDTO;
import com.ehome.poct.core.api.dto.ReportListDTO;
import com.ehome.poct.core.api.dto.ReportQry;
import com.ehome.poct.core.api.dto.check.ReportDTO;
import com.ehome.poct.core.api.dto.report.*;
import com.ehome.poct.core.api.feign.CheckDataClient;
import com.ehome.poct.core.api.feign.OrderClient;
import com.ehome.poct.core.api.feign.ReportClient;
import com.ehome.poct.core.api.feign.TestReportConfigClient;
import com.ehome.poct.core.api.qry.CheckDataQry;
import com.ehome.poct.core.api.vo.CheckReportPageVO;
import com.ehome.poct.core.api.vo.CheckReportVO;
import com.ehome.poct.core.api.vo.ReportDetailVO;
import com.ehome.poct.core.api.vo.ReportListVO;
import com.ehome.poct.core.api.vo.report.TestReportConfRecordVO;
import com.ehome.poct.core.api.vo.report.TestReportConfVO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @description:金标仪列表
 * @author: muqiu
 * @time: 2022/3/22 14:48
 */
@Service
@AllArgsConstructor
@Slf4j
public class JbyReportServiceImpl implements ReportService {
    private static final Integer INVALID = 24;

    private final ReportClient reportClient;

    private final CheckDataClient checkDataClient;

    private final TestReportConfigClient testReportConfigClient;

    private final ClinicClient clinicClient;

    private final OrderClient orderClient;


    @Override
    public CheckReportPageVO list(ReportListDTO dto) {
        ReportQry reportQry = new ReportQry();
        BeanUtils.copyProperties(dto, reportQry);
        if (dto.getPayStatus() != null) {
            if (dto.getPayStatus() == -1) {
                reportQry.setPayStatus(0);
                reportQry.setStartTime(LocalDateTime.MIN);
                reportQry.setEndTime(LocalDateTime.now().minusHours(24));
            }
            if (dto.getPayStatus() == 0) {
                reportQry.setStartTime(LocalDateTime.now().minusHours(24));
                reportQry.setEndTime(LocalDateTime.now());
            }
        }
        Page<CheckReportVO> page = reportClient.pageJby(reportQry);
        List<ReportListVO> list = new ArrayList<>();
        page.getList().forEach(r -> {
            ReportListVO reportListVO = new ReportListVO();
            reportListVO.setReportId(r.getBloodCheckReportId());
            reportListVO.setReportName(r.getReportName());
            reportListVO.setPayOrderNo(r.getOrderNo());
            reportListVO.setCreateTime(r.getCreateTime());
            reportListVO.setPatientName(r.getPatientName());
            this.getOrderStatus(r, reportListVO);
            list.add(reportListVO);
        });
        return new CheckReportPageVO(page.getTotal(), list);
    }

    @Override
    public void deleteById(DelReportDTO delReportDTO) {
        reportClient.deleteJby(delReportDTO);
    }

    @Override
    public ReportDetailVO getOneByOrderNoPrint(String orderNo, Boolean local) {
        return null;
    }

    @Override
    public void toSendStatus(Long clinicId, String status) {

    }

    @Override
    public void createReport(ReportReqDTO reportReqDTO) {
        //检测数据
        var testData = checkDataClient.queryJby(new CheckDataQry().setIds(reportReqDTO.getTestDataIds()));
        if (StrUtil.isBlankIfStr(reportReqDTO.getOrderNo())) {
            //生成报告并保存
            reportClient.createReport(new ReportRequestDTO(reportReqDTO, testData));
            return;
        }
        checkOrderStatus(reportReqDTO.getOrderNo(), orderClient);
        reportClient.createReport(new ReportRequestDTO(reportReqDTO, testData));
    }

    @Override
    public List<ReportDTO> getSummary(String orderNo) {
        return reportClient.getSummaryJby(orderNo);
    }

    @Override
    public void reportConf(ReportConfigDTO reportConfigDTO) {
        log.info("account:{}",reportConfigDTO.getAccount());
        //诊所相关信息
        var clinic = clinicClient.getOne(new TermClinicDTO().setPhone(reportConfigDTO.getAccount()));
        if (clinic == null) {
            throw new BizException(990924, "账号不存在！");
        }
        log.info("clinicId{}", clinic.getTermClinicId());
        //保存报告配置记录
        if (reportConfigDTO.getTestReportConfId() != null) {
            testReportConfigClient.updateReportConf(  new TestReportConfDTO().setTestReportConfId(reportConfigDTO.getTestReportConfId()).setClinicId(clinic.getTermClinicId()).setReportStatus(reportConfigDTO.getReportStatus()).setStartTime(reportConfigDTO.getStartTime()).setEndTime(reportConfigDTO.getEndTime()).setOperator(UserThreadLocal.getUser().getName()));
        } else {
            var testReportConfVO = testReportConfigClient.getOne(new TestReportConfDTO().setClinicId(clinic.getTermClinicId()));
            if (testReportConfVO != null) {
                throw new BizException(199912, "该诊所已有报告配置！");
            }
            testReportConfigClient.reportConf(new TestReportConfDTO().setTestReportConfId(reportConfigDTO.getTestReportConfId()).setClinicId(clinic.getTermClinicId()).setReportStatus(reportConfigDTO.getReportStatus()).setStartTime(reportConfigDTO.getStartTime()).setEndTime(reportConfigDTO.getEndTime()).setOperator(UserThreadLocal.getUser().getName()));
        }
        //查询更改前配置状态
        TestReportConfVO testReportConf = null;
        if (reportConfigDTO.getTestReportConfId() != null) {
            testReportConf = testReportConfigClient.getById(reportConfigDTO.getTestReportConfId());
        }
        //保存报告配置修改记录
        testReportConfigClient.reportConfRecord(new TestReportConfRecordDTO().setUpdateBefore(testReportConf == null ? 0 : testReportConf.getReportStatus()).setUpdateAfter(reportConfigDTO.getReportStatus()).setClinicId(clinic.getTermClinicId()).setOperator(UserThreadLocal.getUser().getName()));
        //修改报告展示和隐藏
        reportClient.reportConfigJby(new TestReportConfigDTO().setClinicId(clinic.getTermClinicId()).setStartTime(reportConfigDTO.getStartTime()).setEndTime(reportConfigDTO.getEndTime()).setDisabled(reportConfigDTO.getReportStatus() == 0 ? 1 : 0));
    }

    @Override
    public PageInfo<TestReportConfVO> reportConfPage(ReportConfigQry reportConfigQry) {
        if (StrUtil.isNotBlank(reportConfigQry.getAccount())) {
            var clinicInfo = clinicClient.getOne(new TermClinicDTO().setPhone(reportConfigQry.getAccount()));
            if (clinicInfo == null) {
                return new PageInfo<>();
            }
            reportConfigQry.setClinicId(clinicInfo.getTermClinicId());
        }
        var page = testReportConfigClient.page(reportConfigQry);
        page.getList().forEach(r -> {
            var clinic = clinicClient.getById(r.getClinicId());
            if (null != clinic) {
                r.setShortId(clinic.getShortId());
                r.setClinicName(clinic.getName());
                r.setAccount(clinic.getPhone());
            }
        });
        return page;
    }

    @Override
    public PageInfo<TestReportConfRecordVO> reportConfRecord(ReportConfigRecordDTO reportConfigRecordDTO) {
        return testReportConfigClient.recordPage(reportConfigRecordDTO);
    }

    @Override
    public ClinicInfoVO clinicInfo(String account) {
        var clinic = clinicClient.getOne(new TermClinicDTO().setPhone(account));
        return clinic == null ? null : new ClinicInfoVO().setAccount(clinic.getPhone()).setClinicName(clinic.getName());
    }


    /**
     * 订单状态
     *
     * @param checkReportVO
     * @param reportListVO
     * @return
     */
    public void getOrderStatus(CheckReportVO checkReportVO, ReportListVO reportListVO) {
        if (checkReportVO.getPayStatus() == 0) {
            Duration duration = Duration.between(checkReportVO.getCreateTime(), LocalDateTime.now());
            if (duration.toHours() > INVALID) {
                reportListVO.setPayStatus(-1);
                return;
            }
            reportListVO.setPayStatus(0);
            reportListVO.setInvalidTime(24 * 3600 - duration.toSeconds());
            return;
        }
        reportListVO.setPayStatus(20);
    }

    /**
     * 血常规面支付下单后更改金标仪报告状态
     *
     * @param orderNo
     * @return
     */
    public void updateReportStatus(String orderNo) {
        reportClient.updateReportStatus(orderNo);
    }
}
